#include<at89c51ed2.h>
#include<stdio.h>
#include<mcs51reg.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include "io.h"


int busy;

void lcdData(char val,int reg)__critical
{	
	
	if(reg==0){
	
	xdata char volatile *test;   //pointer pointing to an address in xdata space 
	test=(xdata char*)0xF000; //assigning specific address 0xFFFF to pointer
	P0_1=1;	
	*test=val;//debug data value 
	}
	if(reg==1){
	
	xdata char volatile *test;   //pointer pointing to an address in xdata space 
	test=(xdata char*)0xF001; //assigning specific address 0xFFFF to pointer
	P0_1=1;	
	*test=val;//debug data value 
	}
	
	


}



int lcdDataRead()
{	

	int val;
	
	xdata int volatile *test;
	
	test=(xdata int*)0xF002; //assigning specific address 0xFFFF to pointer
	val=*test;/*debug data value */
	lcdData(0x10,0);
	//lcdData(0x0F,0);
	return val;
	
} 





void lcddelay(int time){
	int i;
	for(i=0;i<time+1;i++){
	}
}	
	
void checkBusyFlag()
{
	volatile int val;

	val=lcdDataRead();
	val&=0x80;
	while(val!=0x00)
	{
		val=lcdDataRead();
		val&=0x80;
		printf("LCD Busy \n\r");
	}


}

/******************************************************************************************/
/*************************************************************************************************************************************/
// Name: lcdinit()
// Description: Initializes the LCD (see Figure 25 on page 212
//  of the HD44780U data sheet).
void lcdinit(){ 

	/*Unlock Commands*/
	lcddelay(16000);
	
	lcdData(0x30,0);
		
	/*wait for more than 4.1 ms*/
	
	lcddelay(6000);
	
	lcdData(0x30,0);
	
	/*wait for 100 us*/
	
	lcddelay(6000);
	
	lcdData(0x30,0);
	
	//printf("3\n\r");
	
	/*Function Set Command*/
	//lcddelay(); /*Poll for BF=0*/
	lcddelay(500);
	
	lcdData(0x38,0);
	
	//printf("4\n\r");
	/*turn display OFF*/
	//lcddelay(); /*Poll for BF=0*/
	lcddelay(500);
	
	lcdData(0x08,0);
	//printf("5\n\r");
	/*turn display ON*/
	//lcddelay(); /*Poll for BF=0*/
	lcddelay(500);
	
	lcdData(0x0F,0); /*c*/
	
	/*Entry Mode Set Command*/
	//lcddelay(); /*Poll for BF=0*/
	lcddelay(500);
	
	lcdData(0x06,0);
	
	
	/*clear screen and send cursor home*/
	//lcddelay(); /*Poll for BF=0*/
	lcddelay(500);
	
	lcdData(0x01,0);
	lcddelay(500);
	
}
/**************************************************************/




/*set DDRAM Address*/
void lcdgotoaddr(unsigned char addr){

	 
	addr|=0x80;
	
	checkBusyFlag(); /*Poll for BF=0*/
	
	lcdData(addr,0);	
	
}


void decPoint_hexPoint(int val)
{

int act;
act=0;
	if(val<=15){
	act=val;   //1st line
	}
	else if(val>=16&&val<=31){
	act=val+48; //HEX 30  //2nd line
	}
	else if(val>=32&&val<=47){
	act=val-16; //HEX 10  //3rd line
	}
	else /*if(val>=48&&val<=63)*/{
	act=val+32; //HEX 20 //4th line
	}
	
	
	lcdgotoaddr(act);
}

/**********************************************************************************************/



void lcdgotoloc(int x,int y)
{
	

if(y==0){
	decPoint_hexPoint(x);
	
	}
if(y==1){
	decPoint_hexPoint(16+x);
	}
if(y==2){
	decPoint_hexPoint(32+x);
	}
if(y==3){
	decPoint_hexPoint(48+x);
	}

}


/**************************************************************************************/
/************************************************/
void lcdputch(char cc)
{
	
	//lcddelay(500); /*Poll for BF=0*/
	checkBusyFlag(); /*Poll for BF=0*/

	lcdData(cc,1);
}
/**********************************************/

void lcdputstr(char *val){ //put characters in a string
	int i;
	int x_Counter;
	
	int y;
	int currentAddr;
	y=0;
	currentAddr=lcdDataRead();
	currentAddr&=0x7F;
	
	//currentAddr=currentAddr-1;
	
	if(currentAddr<=0x0F){
		y=0;
		
	}
	else if(currentAddr>=0x40&&currentAddr<=0x4F){
		y=1;
		currentAddr=currentAddr-0x40;
	
	}
	else if(currentAddr>=0x10&&currentAddr<=0x1F){
		y=2;
		currentAddr=currentAddr-0x10;
	}
	else if(currentAddr>=0x50&&currentAddr<=0x5F){
		y=3;
		currentAddr=currentAddr-0x50;
	}
	
	//lcdgotoloc(1,15);
	
	x_Counter=16-currentAddr;	



		for(i=0;i<=(strlen(val)-1);i++){
		
			lcdputch(val[i]);
			
			
			x_Counter--;
			
			
			if(y==3&&x_Counter==0){
				y=0;
				lcdgotoloc(0,y);
				x_Counter=16;
			}
			
			if(x_Counter==0){
				
				y=y+1;
				lcdgotoloc(0,y);
				x_Counter=16;
			}
			
		}			
		
	
}	
				
		
void lcdputstring(char *val,int x,int y){ //put characters in a string
	int i;
	int x_Counter;
	
	//lcdgotoloc(x,y);
	
	x_Counter=16-x;	
	


		for(i=0;i<=(strlen(val)-1);i++){
		
			lcdputch(val[i]);
			
			
			x_Counter--;
		
			
			if(y==3&&x_Counter==0){
				y=0;
				lcdgotoloc(0,y);
				x_Counter=16;
			}
			
			if(x_Counter==0){
				
				y=y+1;
				lcdgotoloc(0,y);
				x_Counter=16;
			}
			
		}			
		
	
}	



/************************************************************************************************/
int lcd_asciiInput(char * val){
int num; //was 3
int stop;
int ans;
int i;
int mul;
int j;
char * val2;

val2=(char *)malloc(50);
i=0;
j=0;
stop=0;
while(i<strlen(val)){
	if(val[i]=='0'&&stop==0&&i>0){
	}
	else{
		val2[j]=val[i];
		stop=1;
		j++;
	}
i++;	
}

i=strlen(val2)-1;

//printf("%d",i);

mul=1;
ans=0;

while(i>=0)
	{

	if(val2[i]=='A'||val2[i]=='a'){
		num=10;
	}
	
	else if(val2[i]=='B'||val2[i]=='b'){
		num=11;
	}
	else if(val2[i]=='C'||val2[i]=='c'){
		num=12;
	}
	else if(val2[i]=='D'||val2[i]=='d'){
		num=13;
	}
	else if(val2[i]=='E'||val2[i]=='e'){
		num=14;
	}
	else if(val2[i]=='F'||val2[i]=='f'){
		num=15;
	}
	else{
		
		num=val2[i]-48;
		
	}
	
	ans=ans+mul*num;
	//printf("%d\t%d\n",ans,i);
	mul=mul*16;
	i--;
	}
free(val2);

return ans;
}





















int lcd_singleCharconv(char val){
int num;
	
	if(val=='A'||val=='a'){
		num=10;
	}
	
	else if(val=='B'||val=='b'){
		num=11;
	}
	else if(val=='C'||val=='c'){
		num=12;
	}
	else if(val=='D'||val=='d'){
		num=13;
	}
	else if(val=='E'||val=='e'){
		num=14;
	}
	else if(val=='F'||val=='f'){
		num=15;
	}
	else{
		num=val-48;
		
	}

return num;
}

void lcdgotoxy(unsigned char row,unsigned char column){
	int x;
	int y;
	
	x=lcd_singleCharconv(column);
	y=lcd_singleCharconv(row);
	
	lcdgotoloc(x,y);

}


int bin2dec(char * val){
	int i;
	int ans;
	int mul;
	
	i=strlen(val)-1;
	mul=1;
	ans=0;
	while(i>=0){
	
	ans=ans+mul*(val[i]-48);
	mul=mul*2;
	i--;
	}


	return ans;
}

